package com.liang.lollipop.lreader.activity;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.graphics.Rect;
import android.os.Build;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.TextInputEditText;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.AppCompatSeekBar;
import android.support.v7.widget.AppCompatSpinner;
import android.support.v7.widget.CardView;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewAnimationUtils;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.SeekBar;
import android.widget.TextView;

import com.liang.lollipop.lreader.R;
import com.liang.lollipop.lreader.adapter.AppInfoAdapter;
import com.liang.lollipop.lreader.base.BaseActivity;
import com.liang.lollipop.lreader.bean.AppInfo;
import com.liang.lollipop.lreader.bean.ModelBean;
import com.liang.lollipop.lreader.service.MaskingService;
import com.liang.lollipop.lreader.service.QuickSettingService;
import com.liang.lollipop.lreader.util.AppInfoUtil;
import com.liang.lollipop.lreader.util.DensityUtil;
import com.liang.lollipop.lreader.util.ModelDAO;
import com.liang.lollipop.lreader.util.Settings;
import com.liang.lollipop.lreader.util.TaskUtils;

import java.util.ArrayList;

/**
 * @author Lollipop
 * 主页
 */
public class MainActivity extends BaseActivity implements
        AppCompatSeekBar.OnSeekBarChangeListener,
        TextWatcher,
        AppCompatSpinner.OnItemSelectedListener{

    private FloatingActionButton floatingActionButton;
    public static final String ACTION = "QuickSettingService";
    private View maskView;
    private CardView cornersView;
    private TextView alphaTextView;
    private TextView greenTextView;
    private TextView redTextView;
    private TextView blueTextView;
    private TextView animTextView;
    private TextView cornersTextView;
    private AppCompatSeekBar alphaBar;
    private AppCompatSeekBar greenBar;
    private AppCompatSeekBar redBar;
    private AppCompatSeekBar blueBar;
    private TextInputEditText modelNameEdit;
    private View modelNameChangeBtn;
    private AppCompatSpinner modelSpinner;
    private AppCompatSpinner pkgSpinner;

    private ModelBean modelBean;
    private ArrayList<ModelBean> modelBeen = new ArrayList<>();
    private ArrayAdapter<ModelBean> modelAdapter;
    private ArrayList<AppInfo> appInfoList = new ArrayList<>();
    private ModelDAO modelDAO;
    private Animator hideAnimator;
    private Animator showAnimator;
    private AppInfoAdapter appInfoAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setShowBack(false);
        setToolBar(R.id.activity_main_toolbar);

        modelDAO = new ModelDAO(this);

        initView();

        changeFABState(Settings.getState(this));
        IntentFilter filter = new IntentFilter();
        filter.addAction(ACTION);
        registerReceiver(MaskingReceiver, filter);
        queryAppInfoList();

        openPermissions();
    }

    private void initView(){
        //model选择器
        modelSpinner = (AppCompatSpinner) findViewById(R.id.activity_main_type);
        modelAdapter = new ArrayAdapter<>(this,R.layout.item_simple_spinner,modelBeen);
        modelAdapter.setDropDownViewResource(R.layout.item_simple_spinner_dropdown);
        modelSpinner.setAdapter(modelAdapter);
        modelSpinner.setOnItemSelectedListener(this);
        //关联其他引用包
        pkgSpinner = (AppCompatSpinner) findViewById(R.id.activity_main_pkg);
        appInfoAdapter = new AppInfoAdapter(appInfoList,this);
        pkgSpinner.setAdapter(appInfoAdapter);
        pkgSpinner.setOnItemSelectedListener(this);
        //名字修改
        modelNameEdit = (TextInputEditText) findViewById(R.id.activity_main_model_name);
        modelNameEdit.addTextChangedListener(this);
        modelNameChangeBtn = findViewById(R.id.activity_main_model_name_change);
        modelNameChangeBtn.setOnClickListener(this);
        //启动按钮
        floatingActionButton = (FloatingActionButton) findViewById(R.id.activity_main_fab);
        floatingActionButton.setOnClickListener(this);
        //效果预览
        maskView = findViewById(R.id.activity_main_mask);
        cornersView = (CardView) findViewById(R.id.activity_main_corners);
        //色值显示
        alphaTextView = (TextView) findViewById(R.id.activity_main_alpha_text);
        greenTextView = (TextView) findViewById(R.id.activity_main_green_text);
        redTextView = (TextView) findViewById(R.id.activity_main_red_text);
        blueTextView = (TextView) findViewById(R.id.activity_main_blue_text);
        animTextView = (TextView) findViewById(R.id.activity_main_anim_text);
        cornersTextView = (TextView) findViewById(R.id.activity_main_corners_text);
        //色值调整
        alphaBar = (AppCompatSeekBar) findViewById(R.id.activity_main_alpha_bar);
        alphaBar.setOnSeekBarChangeListener(this);

        greenBar = (AppCompatSeekBar) findViewById(R.id.activity_main_green_bar);
        greenBar.setOnSeekBarChangeListener(this);

        redBar = (AppCompatSeekBar) findViewById(R.id.activity_main_red_bar);
        redBar.setOnSeekBarChangeListener(this);

        blueBar = (AppCompatSeekBar) findViewById(R.id.activity_main_blue_bar);
        blueBar.setOnSeekBarChangeListener(this);

        AppCompatSeekBar animBar = (AppCompatSeekBar) findViewById(R.id.activity_main_anim_bar);
        animBar.setOnSeekBarChangeListener(this);

        AppCompatSeekBar cornersBar = (AppCompatSeekBar) findViewById(R.id.activity_main_corners_bar);
        cornersBar.setOnSeekBarChangeListener(this);
        //色值的赋值初始化操作
        initColorSeekBar(0);
        //其他bar初始化
        long duration = Settings.getDuration(this)/100;
        if(duration<1)
            duration = 1;
        animBar.setProgress((int)duration);
        onSeekBarChange(animBar);

        cornersBar.setProgress(Settings.getCorners(this));
        onSeekBarChange(cornersBar);
    }

    @Override
    protected void onResume() {
        super.onResume();
        getData();
    }

    private void getData(){
        TaskUtils.addTask(new TaskUtils.OnUICallBack<ArrayList<ModelBean>,Object>(this) {
            @Override
            public void onUISuccess(ArrayList<ModelBean> result) {
                modelBeen.clear();
                if(result!=null)
                    modelBeen.addAll(result);
                modelAdapter.notifyDataSetChanged();
                modelSpinner.setSelection(0);
            }

            @Override
            public void onUIError(Exception e, int code, String msg) {
                T(getString(R.string.error_model_list)+e.getLocalizedMessage());
            }

            @Override
            public ArrayList<ModelBean> onBackground(Object[] args) throws Exception {
                ModelDAO dao = (ModelDAO) args[0];
                Context context = (Context) args[1];
                //获得当前数据库中的预设项目
                ArrayList<ModelBean> arrayList = dao.selectAll();
                //如果没有预设，那么就添加当前默认设置项为预设
                if(arrayList==null||arrayList.size()<1){
                    ModelBean bean = new ModelBean();
                    bean.sort = 0;
                    bean.project = "";
                    bean.name = context.getString(R.string.preset);
                    bean.value = Color.argb(Settings.getAlpha(context),
                            Settings.getRed(context),
                            Settings.getGreen(context),
                            Settings.getBlue(context));
                    dao.insert(bean);
                    arrayList = dao.selectAll();
                }
                return arrayList;
            }
        },modelDAO,this);
    }

    private void queryAppInfoList(){
        TaskUtils.addTask(new TaskUtils.OnHandlerCallBack<ArrayList<AppInfo>,Context>(handler) {

            @Override
            public void onUISuccess(ArrayList<AppInfo> result) {
                appInfoList.clear();
                appInfoList.add(new AppInfo(null,null,getString(R.string.string_null),getString(R.string.not_associated)));
                if(result!=null)
                    appInfoList.addAll(result);
                appInfoAdapter.notifyDataSetChanged();
                selectedAppInfo();
            }

            @Override
            public void onUIError(Exception e, int code, String msg) {
                T(getString(R.string.error_model_list)+e.getLocalizedMessage());
            }

            @Override
            public ArrayList<AppInfo> onBackground(Context... args) throws Exception {
                Context context = args[0];
                return AppInfoUtil.queryAppInfoNoIntent(context);
            }
        },this);
    }

    private void selectedAppInfo(){
        if(modelBean!=null){
            TaskUtils.addTask(new TaskUtils.OnHandlerCallBack<Integer,Object>(handler) {
                @Override
                public void onUISuccess(Integer result) {
                    if(result!=null){
                        pkgSpinner.setSelection(result);
                    }else{
                        pkgSpinner.setSelection(0);
                    }
                }

                @Override
                public void onUIError(Exception e, int code, String msg) {
                    T(getString(R.string.error_app_list)+e.toString());
                }

                @Override
                public Integer onBackground(Object... args) throws Exception {
                    ArrayList<AppInfo> list = (ArrayList<AppInfo>) args[0];
                    String name = (String) args[1];
                    for(int i = 0,count=list==null?0:list.size();i<count;i++){
                        if(name.equals(list.get(i).pkgName))
                            return i;
                    }
                    return 0;
                }
            },appInfoList,modelBean.project);
        }
    }

    private void initColorSeekBar(int color){
        alphaBar.setProgress(Color.alpha(color));
        onSeekBarChange(alphaBar);
        greenBar.setProgress(Color.green(color));
        onSeekBarChange(greenBar);
        redBar.setProgress(Color.red(color));
        onSeekBarChange(redBar);
        blueBar.setProgress(Color.blue(color));
        onSeekBarChange(blueBar);

        changeMaskView();
    }

    private void onSeekBarChange(SeekBar bar){
        switch (bar.getId()){
            case R.id.activity_main_alpha_bar:
                onSeekBarChange(alphaTextView,R.string.string_alpha,bar.getProgress());
                break;
            case R.id.activity_main_red_bar:
                onSeekBarChange(redTextView,R.string.string_red,bar.getProgress());
                break;
            case R.id.activity_main_green_bar:
                onSeekBarChange(greenTextView,R.string.string_green,bar.getProgress());
                break;
            case R.id.activity_main_blue_bar:
                onSeekBarChange(blueTextView,R.string.string_blue,bar.getProgress());
                break;
            case R.id.activity_main_anim_bar:
                onSeekBarChange(animTextView,R.string.string_anim,bar.getProgress()*100);
                break;
            case R.id.activity_main_corners_bar:
                onSeekBarChange(cornersTextView,R.string.string_corners,bar.getProgress());
                cornersView.setRadius(DensityUtil.dip2px(this,bar.getProgress()));
                break;
        }
    }

    private void onSeekBarChange(TextView view,int strId,int size){
        view.setText(String.format(getString(strId),size));
    }

    private void changeMaskView(){
        int color = Color.argb(alphaBar.getProgress(),redBar.getProgress(),greenBar.getProgress(),blueBar.getProgress());
        maskView.setBackgroundColor(color);
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.activity_main_fab:
                onFABClick();
                break;
            case R.id.activity_main_model_name_change:
                changeModelName();
                break;
        }
    }

    private void changeModelName(){
        String newName = modelNameEdit.getText().toString().trim();
        if(TextUtils.isEmpty(newName)){
            modelNameEdit.setError(getString(R.string.error_model_name_not_null));
            return;
        }
        modelBean.name = newName;
        TaskUtils.addTask(new TaskUtils.OnHandlerCallBack<Boolean,Object>(handler) {

            @Override
            public void onUISuccess(Boolean result) {
                hideModelNameBtn();
//                modelSpinner.setSelection(modelSpinner.getSelectedItemPosition());
                modelAdapter.notifyDataSetChanged();
                cornersView.findFocus();
                cornersView.requestFocus();
            }

            @Override
            public void onUIError(Exception e, int code, String msg) {
                T(getString(R.string.error_change_model_name)+e.toString());
            }

            @Override
            public Boolean onBackground(Object... args) throws Exception {
                ModelDAO dao = (ModelDAO) args[0];
                ModelBean bean = (ModelBean) args[1];
                return dao.update(bean)==1;
            }
        },modelDAO,modelBean);
    }

    private void onFABClick(){
        boolean type = !Settings.getState(this);
        Intent intent = new Intent(this,MaskingService.class);
        if(type){
            intent.putExtra(MaskingService.ARG_TYPE,MaskingService.TYPE_ON);
            intent.putExtra(MaskingService.ARG_COLOR,modelBean.value);
            intent.putExtra(MaskingService.ARG_ID,modelBean.id);
        }else{
            intent.putExtra(MaskingService.ARG_TYPE,MaskingService.TYPE_OFF);
        }
        if(Build.VERSION.SDK_INT>= Build.VERSION_CODES.O){
            startForegroundService(intent);
        }else{
            startService(intent);
        }
    }

    private void changeFABState(boolean isOpen){
        if(isOpen){
            floatingActionButton.setImageResource(R.drawable.ic_visibility_white_24dp);
            floatingActionButton.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(this,R.color.colorAccent)));
        }else{
            floatingActionButton.setImageResource(R.drawable.ic_visibility_off_white_24dp);
            floatingActionButton.setBackgroundTintList(ColorStateList.valueOf(0xFFBBBBBB));
        }
    }

    private BroadcastReceiver MaskingReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            changeFABState(intent.getIntExtra(MaskingService.ARG_TILE_STATE,MaskingService.TYPE_OFF)==MaskingService.TYPE_ON);
        }
    };

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main,menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()){
            case R.id.menu_main_add:
                addModel();
                break;
            case R.id.menu_main_swap:
                startActivity(new Intent(this,ModelManagerActivity.class));
                break;
            case R.id.menu_main_setting:
                startActivity(new Intent(this,SettingActivity.class));
                break;
        }
        return super.onOptionsItemSelected(item);
    }

    private void addModel(){
        TaskUtils.addTask(new TaskUtils.OnUICallBack<ArrayList<ModelBean>,Object>(this) {
            @Override
            public void onUISuccess(ArrayList<ModelBean> result) {
                modelBeen.clear();
                if(result!=null)
                    modelBeen.addAll(result);
                modelAdapter.notifyDataSetChanged();
                T(getString(R.string.model_add_success));
            }

            @Override
            public void onUIError(Exception e, int code, String msg) {
                T(getString(R.string.error_add_model)+e.getLocalizedMessage());
            }

            @Override
            public ArrayList<ModelBean> onBackground(Object[] args) throws Exception {
                ModelDAO dao = (ModelDAO) args[0];
                int sort = (int) args[1];
                Context context = (Context) args[2];

                //添加默认bean
                ModelBean bean = new ModelBean();
                bean.sort = sort;
                bean.project = "";
                bean.name = context.getString(R.string.preset)+String.valueOf(sort);
                bean.value = 0;
                dao.insert(bean);

                return dao.selectAll();
            }
        },modelDAO,modelBeen.size(),this);
    }

    @Override
    public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
        if(!b)
            return;
        onSeekBarChange(seekBar);
        if(seekBar.getId()==R.id.activity_main_anim_bar
                ||seekBar.getId()==R.id.activity_main_corners_bar)
            return;
        changeMaskView();
    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {

    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
        switch (seekBar.getId()){
            case R.id.activity_main_alpha_bar:
                if(modelBean!=null)
                    modelBean.value = Color.argb(seekBar.getProgress(),
                            Color.red(modelBean.value),
                            Color.green(modelBean.value),
                            Color.blue(modelBean.value));
                modelDAO.update(modelBean);
                break;
            case R.id.activity_main_red_bar:
                if(modelBean!=null)
                    modelBean.value = Color.argb(Color.alpha(modelBean.value),
                            seekBar.getProgress(),
                            Color.green(modelBean.value),
                            Color.blue(modelBean.value));
                modelDAO.update(modelBean);
                break;
            case R.id.activity_main_green_bar:
                if(modelBean!=null)
                    modelBean.value = Color.argb(Color.alpha(modelBean.value),
                            Color.red(modelBean.value),
                            seekBar.getProgress(),
                            Color.blue(modelBean.value));
                modelDAO.update(modelBean);
                break;
            case R.id.activity_main_blue_bar:
                if(modelBean!=null)
                    modelBean.value = Color.argb(Color.alpha(modelBean.value),
                            Color.red(modelBean.value),
                            Color.green(modelBean.value),
                            seekBar.getProgress());
                modelDAO.update(modelBean);
                break;
            case R.id.activity_main_anim_bar:
                Settings.setDuration(this,seekBar.getProgress()*100);
                break;
            case R.id.activity_main_corners_bar:
                Settings.setCorners(this,seekBar.getProgress());
                break;
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        unregisterReceiver(MaskingReceiver);
        onSettingChange();
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {

    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        if(modelBean==null){
            hideModelNameBtn();
            return;
        }
        if(s.toString().equals(modelBean.name)){
            hideModelNameBtn();
        }else{
            showModelNameBtn();
        }
    }

    @Override
    public void afterTextChanged(Editable s) {

    }

    private void hideModelNameBtn(){
        //已经不显示了，就不再操作
        if(!modelNameChangeBtn.isShown())
            return;
        final int width = modelNameChangeBtn.getWidth();
        final int height = modelNameChangeBtn.getHeight();
        int x = 0;
        int y = 0;
        Rect rect = new Rect();
        if(modelNameChangeBtn.getLocalVisibleRect(rect)){
            x = rect.right;
            y = rect.centerY();
        }
        if(x==0||y==0){
            modelNameChangeBtn.setVisibility(View.GONE);
            return;
        }

        float radius = (float) Math.sqrt(width*width + height*height);
        //关闭动画
        hideAnimator = ViewAnimationUtils.createCircularReveal(modelNameChangeBtn,x,y,radius,0);
        //设置动画时间
        hideAnimator.setDuration(getResources().getInteger(R.integer.animation_duration));
        //监听动画状态，当动画结束时
        hideAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                modelNameChangeBtn.setVisibility(View.GONE);
            }
        });
        if(showAnimator!=null)
            showAnimator.cancel();
        hideAnimator.start();
    }

    private void showModelNameBtn(){
        //已经显示了，就不再操作
        if(modelNameChangeBtn.isShown())
            return;
        modelNameChangeBtn.setVisibility(View.VISIBLE);
        final int width = modelNameChangeBtn.getWidth();
        final int height = modelNameChangeBtn.getHeight();
        int x = 0;
        int y = 0;
        Rect rect = new Rect();
        if(modelNameChangeBtn.getLocalVisibleRect(rect)){
            x = rect.right;
            y = rect.centerY();
        }
        if(x==0||y==0){
            return;
        }

        float radius = (float) Math.sqrt(width*width + height*height);
        //显示动画
        showAnimator = ViewAnimationUtils.createCircularReveal(modelNameChangeBtn,x,y,0,radius);
        //设置动画时间
        showAnimator.setDuration(getResources().getInteger(R.integer.animation_duration));
        if(hideAnimator!=null)
            hideAnimator.cancel();
        showAnimator.start();
    }

    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
        if(parent==modelSpinner){
            modelBean = modelBeen.get(position);
            initColorSeekBar(modelBean.value);
            modelNameEdit.setText(modelBean.name);
            selectedAppInfo();
        }else if(parent==pkgSpinner){
            AppInfo appInfo = appInfoList.get(position);
            if(modelBean.project.equals(appInfo.pkgName))
                return;
            if(position==0)
                modelBean.project = "";
            else
                modelBean.project = appInfo.pkgName;
            modelDAO.update(modelBean);
        }
        onSettingChange();
    }

    @Override
    public void onNothingSelected(AdapterView<?> parent) {

    }

    private void openPermissions(){
        if(isAccessibilitySettingsOn(this)){
            return;
        }
        if(!Settings.get(this,"openPermissions",true)){
            return;
        }
        new AlertDialog.Builder(this)
                .setTitle(R.string.hint)
                .setMessage(R.string.apply_permission)
                .setNeutralButton(R.string.no_remind, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        Settings.get(MainActivity.this,"openPermissions",false);
                        dialog.dismiss();
                    }
                })
                .setNegativeButton(R.string.refused, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                })
                .setPositiveButton(R.string.travel_to, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    Intent intent = new Intent(android.provider.Settings.ACTION_ACCESSIBILITY_SETTINGS);
                    startActivity(intent);
                    dialog.dismiss();
                }
            }).show();
    }

    // To check if service is enabled
    public static boolean isAccessibilitySettingsOn(Context context) {
        int accessibilityEnabled = 0;
        try {
            accessibilityEnabled = android.provider.Settings.Secure.getInt(context.getContentResolver(),
                    android.provider.Settings.Secure.ACCESSIBILITY_ENABLED);
        } catch (android.provider.Settings.SettingNotFoundException e) {
        }

        if (accessibilityEnabled == 1) {
            String services = android.provider.Settings.Secure.getString(context.getContentResolver(),
                    android.provider.Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
            if (services != null) {
                return services.toLowerCase().contains(context.getPackageName().toLowerCase());
            }
        }
        return false;
    }

    private void onSettingChange(){
        sendBroadcast(new Intent(SettingActivity.ACTION_SETTING_CHANGE));
    }

}
